package com.kgcx.gateway.filter;

import com.alibaba.fastjson.JSONObject;
import com.kgcx.common.bean.ReturnData;
import com.kgcx.common.utils.IpUtils;
import com.kgcx.common.utils.TokenUtils;
import com.kgcx.gateway.service.TokenService;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.entity.ContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;

@Component
@Slf4j
public class TokenFilter extends ZuulFilter {
    @Value("${kgcx.token.enable:true}")
    private boolean tokenEnable;
    @Autowired
    private TokenService tokenService;


    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 1;
    }

    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String agent = request.getHeader("User-Agent");
        String ipAddr = IpUtils.getIpAddr(request);
        log.info("请求到达：agent:" + agent + ",ip:" + ipAddr);
        if (tokenEnable) {
            String servletPath = request.getServletPath();
            log.debug("请求到达：" + servletPath);
            if (ArrayUtils.contains(TokenUtils.TOKEN_SKIP_PATH, servletPath)
                    || isActuatorEndpoint(servletPath)) {
                log.debug("无需鉴权：" + servletPath);
                return false;
            }
            log.debug("需要鉴权：" + servletPath);
            return true;
        }
        return false;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String token = request.getHeader("token");
        log.debug("token=" + token);
        String returnInfo;
        if (StringUtils.isNotBlank(token)) {
            try {
                Claims claims = TokenUtils.getClaims(token);
                String subject = claims.getSubject();
                String id = claims.getId();
                Long kid = Long.valueOf(id);
                if (tokenService.validateToken(token, kid, subject)) {
                    return null;
                }
            } catch (ExpiredJwtException e) {
                returnInfo = "token过期";
                log.error(returnInfo, e);
            } catch (Exception e) {
                returnInfo = "内部错误";
                log.error(returnInfo, e);
            }
        }
        returnInfo = "token验证失败";
        ctx.setSendZuulResponse(false);
        ctx.setResponseStatusCode(HttpStatus.SC_OK);
        ctx.getResponse().setContentType(
                ContentType.APPLICATION_JSON.withCharset(StandardCharsets.UTF_8).toString());
        ctx.setResponseBody(JSONObject.toJSONString(new ReturnData<>("-99", returnInfo)));
        log.error("token验证失败,token=" + token);

        return null;
    }

    private boolean isActuatorEndpoint(String path) {
        return StringUtils.startsWithIgnoreCase(path, "/actuator/");
    }

    public static void main(String[] args) {
        Claims claims = TokenUtils.getClaims("eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI1NCIsImlhdCI6MTUyMjEzMjQ1NSwiZXhwIjoxNTM4MDMwMDU1LCJzdWIiOiJjdXN0b21l.rLsyqLshu50KBhXHG28bDs9wP-vT7HIab8x2gc5Ne78");
        String subject = claims.getSubject();
        String id = claims.getId();
        Long kid = Long.valueOf(id);
        System.out.println(subject + "---" + id);
    }
}
